當運算式有多個或多個類別的運算子時,我們會以運算子的 優先性 以及 相依性 來決定運算執行的順序與方向
優先性是運算子彼此之間的執行順序,而優先序高的運算子會優先執行,若優先性相同則以相依性規則執行
相依性決定運算子的執行方向,例如:由左至右執行
以下為常見運算子的優先性與相依性表格:
詳細可看 MDN - 運算子優先序
| 優先性 | 運算子 | 相依性 |
|---|---|---|
| 16 | ++ … | 由右至左 |
| 16 | -- … | 由右至左 |
| 14 | … * … | 由左至右 |
| 14 | … / … | 由左至右 |
| 13 | … + … | 由左至右 |
| 13 | … - … | 由左至右 |
| 11 | … < … | 由左至右 |
| 11 | … > … | 由左至右 |
| 10 | … == … | 由左至右 |
| 10 | … === … | 由左至右 |
| 9 | … & … | 由左至右 |
| 6 | … && … | 由左至右 |
| 5 | ![]() |
由左至右 |
| 3 | … = … | 由右至左 |
當運算式中有多個不同類別運算子,先執行優先順序高的
var a = 2 * 2 + 2 * 3;
console.log(a);
* 優先性最高,而相依性為左至右,所以先執行 2 * 2、2 * 3,得出 var a = 4 + 6;
+ 優先性較 = 高,所以執行 4 + 6 得出 10
= 相依性為右至左,所以 10 賦值到 變數 a 上console.log(1 < 2 < 3); // true
此例優先性相同,< 相依性由左至右執行, 1 < 2 為 true,true 與數字做比較會自動轉型為 1,又因 1 < 3,所以答案為 true
console.log(3 > 2 > 1); // false
此例優先性相同,> 相依性由左至右執行 3 > 2 為 true,true 與數字做比較會自動轉型為 1,而 1 > 1 答案為 false
var a = 1;
var b = 2;
a = b = 3;
console.log(a, b); // 3 3
= 相依性為右至左,所以由 b = 3 開始執行b = 3 為表達式,會回傳值 3
變數 a 經由賦值運算子,將所回傳的 3 賦予至 變數 a
變數 a接收的是b = 3的回傳結果,並非取自於變數 b的值
var a = {};
Object.defineProperty(a, 'b', {
value: 2,
writable: false,
});
a.b = 3;
console.log(a.b); // 2 - 因不能被賦寫
var c = 4;
c = a.b = 5;
console.log(a.b, c); // 2 5
變數 a 為一個空物件,在 變數 a 下新增 屬性 b,設定 屬性 b 值為 2,且不可寫入a.b = 3; 時,因已設定 writable: false 所以 a.b 不能夠被覆寫,會保持 2 的值,故賦予的值 3,也因沒有效果被釋放掉變數 c,賦予值 4;c = a.b = 5;,因 = 相依性由右至左執行,先執行 a.b = 5,a.b 因不能被覆寫,會保持 2 的值,但因 a.b = 5 為表達式,會回傳值 5
a.b = 5 所回傳的值 5 會賦予至 變數 c
變數 c 的值為 5,a.b 的值為 2
var a = {};
Object.defineProperty(a, 'b', {
value: 2,
writable: false,
});
Object.defineProperty(a, 'c', {
value: 3,
writable: false,
});
var d = 4
d = a.c = a.b = 5;
console.log(d, a.b, a.c); // 5 2 3
變數 a 為一個空物件,在 變數 a 下新增 屬性 b 及 屬性 c,設定 屬性 b 值為 2,設定 屬性 c 值為 3,且皆不可寫入變數 d,賦予值 4;d = a.c = a.b = 5;,= 相依性由右至左執行a.b 、 a.c 都不會被覆寫,所以 a.c 先接收 a.b = 5 表達式所回傳的值 5,得出 a.c = 5 表達式並回傳值 5
a.c = 5 所回傳的值 5 會被賦予至 變數 d
變數 d 的值為 5,a.b 的值為 2,a.c 的值為 3